/*
 * @file iso9660_init_supp.c
 *
 *   ISO9660 initialization support routine implementation
 */
#if HAVE_CONFIG_H
#include "config.h"
#endif

#include <malloc.h>
#include <stdio.h>

#include <rtems.h>
#include <rtems/libio_.h>
#include <rtems/seterr.h>

#include "iso9660.h"
#include "iso9660_record.h"

/*
 *   ISO9660 filesystem initialization
 *
 * @param mt_entry            Mount table entry
 * @param op_handle           Filesystem operation handlers table
 * @param file_handlers       File nodes operation handlers table
 * @param directory_handlers  Directory nodes operation handlers table
 * @param mount_options       ISO9660 volume mount options
 * @param version             (only cares of the extension section) Desired
 *                            extensions to allow.
 *
 * @return 0 on success, else -1
 */
int rtems_iso9660_initialize_support(
    rtems_filesystem_mount_table_entry_t        *mt_entry,
    const rtems_filesystem_operations_table    *op_table,
    const rtems_filesystem_file_handlers_r     *file_handlers,
    const rtems_filesystem_file_handlers_r     *directory_handlers,
    const iso9660_mount_options_t              *mount_options,
    iso9660_version_t                            version
)
{
  int                  status = 0;
  iso9660_fs_info_t   *fs = NULL;

  rtems_iso9660_dbg_trace(RTEMS_ISO9660_DEBUG_FSMOUNT,
      "Initializing  iso9660 volume\n");

  /* Initialize the per-volume filesystem info */
  fs = (iso9660_fs_info_t*)calloc(1, sizeof(iso9660_fs_info_t));
  if (fs == NULL)
    rtems_iso9660_error_and_return_minus_one(ENOMEM,
        "init_supp: failed to allocate memory for filesystem info.");

  fs->file_handlers = file_handlers;
  fs->directory_handlers = directory_handlers;
  memcpy(&fs->mount_options, mount_options, sizeof(iso9660_mount_options_t));

  /* Load the volume */
  mt_entry->fs_info = fs;
  status = iso9660_init_volume_info(mt_entry, version);
  if (status)
    rtems_iso9660_error_and_return_minus_one(errno,
        "init_supp: failed to init volume info.");

  /* Initialize the root node */
  mt_entry->mt_fs_root.node_access
    = iso9660_record_create_from_extent(fs->volume.root_record_location, fs);

  if (mt_entry->mt_fs_root.node_access == NULL)
    rtems_iso9660_error_and_return_minus_one(errno,
        "init_supp: failed to create the root record.");

  mt_entry->mt_fs_root.handlers    = directory_handlers;
  mt_entry->mt_fs_root.ops         = op_table;

  errno = 0;
  return 0;
}
